use maxminddb::Reader;
use rocket::{
    fairing::{self, Fairing, Info, Kind},
    Build, Rocket,
};
use std::sync::Arc;

pub struct GeoIpHandler {
    reader: Option<Arc<Reader<Vec<u8>>>>,
}

impl GeoIpHandler {
    pub fn reader(&self) -> Option<Arc<Reader<Vec<u8>>>> {
        self.reader.clone()
    }
}

pub struct GeoIP;

#[rocket::async_trait]
impl Fairing for GeoIP {
    fn info(&self) -> Info {
        Info {
            name: "GeoIP",
            kind: Kind::Ignite | Kind::Singleton,
        }
    }

    async fn on_ignite(&self, rocket: Rocket<Build>) -> fairing::Result {
        let reader = match maxminddb::Reader::open_readfile("geoip/geoip.mmdb") {
            Ok(reader) => Some(Arc::new(reader)),
            Err(err) => {
                eprintln!(
                    "Error reading GeoIP database: {:?}, disabling GeoIP functionality.",
                    err
                );
                return Ok(rocket.manage(GeoIpHandler { reader: None }));
            }
        };
        Ok(rocket.manage(GeoIpHandler { reader }))
    }
}
